#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 30;
int max_thresh = 255;
RNG rng(12345);
int main(){
	src = imread( "/media/st/Application/Ubuntu/dataset/tj/1019/img/1019/training/temp.jpg" ,CV_LOAD_IMAGE_COLOR );
	Rect bbox_ = cv::Rect(290,205,147,125);
	Mat target_img_ = cv::Mat(cv::Size(src.size().width, src.size().height), CV_8UC3,cv::Scalar(152,158,153));
	src(bbox_).copyTo(target_img_(bbox_));

	cvtColor( src, src_gray, CV_BGR2GRAY );//灰度化
	GaussianBlur( src, src, Size(3,3), 0.1, 0, BORDER_DEFAULT );
	blur( src_gray, src_gray, Size(3,3) ); //滤波
	namedWindow( "image", CV_WINDOW_AUTOSIZE );
	imshow( "image", src );
	moveWindow("image",20,20);
	//定义Canny边缘检测图像
	Mat canny_output;
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;
	//利用canny算法检测边缘
	Canny( src_gray, canny_output, thresh, thresh*3, 3 );
	namedWindow( "canny", CV_WINDOW_AUTOSIZE );
	imshow( "canny", canny_output );
	moveWindow("canny",550,20);
	//查找轮廓
	findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
	//计算轮廓矩
	vector<Moments> mu(contours.size() );
	for( int i = 0; i < contours.size(); i++ )
	{ mu[i] = moments( contours[i], false ); }
	//计算轮廓的质心
	vector<Point2f> mc( contours.size() );
	for( int i = 0; i < contours.size(); i++ )
	{ mc[i] = Point2d( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }
 
	//画轮廓及其质心并显示
	Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
	printf("\t\t 几何特性\n");
	for( int i = 0; i< contours.size(); i++ )
	{
		Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
		drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
		circle( drawing, mc[i], 4, color, -1, 8, 0 );		
		rectangle(drawing, boundingRect(contours.at(i)), cvScalar(0,255,0));
		printf("目标%d - 面积：%.2f - 周长: %.2f ", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );
		RotatedRect r = fitEllipse(contours.at(i));
		double majorAxis = r.size.height > r.size.width ? r.size.height : r.size.width;//长轴大小
		double minorAxis = r.size.height > r.size.width ? r.size.width : r.size.height;//短轴大小
		double area = mu[i].m00;//面积
		int perimeter = arcLength(contours.at(i), true);
		double orientation = r.angle;
		double orientation_rads = orientation*3.1416/180;
		printf("- 偏移角度: %.1f\n\n", orientation);
		double diameter = sqrt((4*area)/3.1416);//直径
		double eccentricity = sqrt(1-pow(minorAxis/majorAxis,2));//离心率
		double roundness = pow(perimeter, 2)/(2*3.1416*area);//圆滑度
		line(drawing, Point(mc[i].x, mc[i].y), Point(mc[i].x+30*cos(orientation_rads), mc[i].y+30*sin(orientation_rads)), cvScalar(0,0,200), 3);
		char tam[100];
		sprintf(tam, "%.2f", orientation);
		putText(drawing, tam, Point(mc[i].x, mc[i].y), FONT_HERSHEY_SIMPLEX, 0.5, cvScalar(0,220,120),1.5);
	}
	namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
	imshow( "Contours", drawing );
	moveWindow("Contours",1100,20);
	waitKey(0);
	src.release();
	src_gray.release();
	return 0;
}
